package cn.foolishbird.crow.captcha;

import cn.foolishbird.crow.core.CrowEnum;

import java.util.Objects;

/**
 * 抽象验证生成策略
 *
 * @author foolish-bird
 */
public abstract class AbstractCaptchaStrategy<V> implements CaptchaStrategy<V> {

    /**
     * 策略编号
     */
    private Enum<? extends CrowEnum> identity;

    /**
     * 验证码id生成器
     */
    protected CaptchaIdGenerator idGenerator;

    /**
     * 验证码存储策略
     */
    protected CaptchaRepository<V> repository;

    @Override
    public Enum<? extends CrowEnum> identity() {
        return this.identity;
    }

    @Override
    public Captcha<V> createCaptcha() {
        if (Objects.isNull(idGenerator)) {
            throw new IllegalArgumentException("验证码id生成器不为空");
        }
        Captcha<V> captcha = this.doCreateCaptcha(idGenerator.generator());
        repository.save(captcha);
        return captcha;
    }

    @Override
    public boolean verifyCaptcha(Captcha<V> captcha) {
        // 根据id查询验证码信息
        Captcha<V> repository = this.repository.query(captcha.captchaId());
        // 未查询，直接返回false
        if (Objects.isNull(repository)) {
            return false;
        }
        // 查询到，但是校验验证码是无效验证码
        if (!verify(captcha, repository)) {
            return false;
        }

        // 标记使用过
        this.repository.redeem(captcha);
        return true;
    }

    /**
     * 生成验证码
     *
     * @param captchaId
     * @return
     */
    protected abstract Captcha<V> doCreateCaptcha(String captchaId);

    /**
     * 校验是否有效
     *
     * @param captcha
     * @param repository
     */
    protected abstract boolean verify(Captcha<V> captcha, Captcha<V> repository);
}
